#include "Animation.h"

Animation::Animation()
	: Sprite()
	, isLooping(false)
	, nbFrames(0)
	, currentFrame(0)
	, frameRate(0.0f)
	, currentTime(0.0f)
	, anim(0) {

}

Animation::Animation(const std::string &path, int xPos, int yPos, int wPos, int hPos, int xSrc, int ySrc, int wSrc, int hSrc, int offsetSrc, int frames, int fps, bool loop, bool horz) 
	: Sprite(path, xPos, yPos, wPos, hPos)
	, isLooping(loop)
	, nbFrames(frames)
	, currentFrame(0)
	, frameRate(1.0f / (float)fps)
	, currentTime(0.0f)
	, anim(0) {
	// create the array
	anim = new SDL_Rect[nbFrames];
	
	// fill it
	for (int i = 0; i < nbFrames; i++) {
		if (horz) {
			// offset the images on the x axis
			anim[i].x = xSrc + i * wSrc + i * offsetSrc;
			anim[i].y = ySrc;
		} else {
			// offset the images on the y axis
			anim[i].x = xSrc;
			anim[i].y = ySrc + i * hSrc + i * offsetSrc;
		}

		// the width and height will always be the same, no matter if its vertical or horizontal
		anim[i].w = wSrc;
		anim[i].h = hSrc;
	}

	// start out at the first frame
	SetSrcRect(anim[0]);
}

void Animation::SetAnimation(int xSrc, int ySrc, int wSrc, int hSrc, int offsetSrc, int frames, int fps, bool loop, bool horz) {
	isLooping = loop;
	nbFrames = frames;
	currentFrame = 0;
	frameRate = 1.0f / (float)fps;
	currentTime = 0.0f;

	// clean up the old anim and create the new one
	if (anim != 0) {
		delete[] anim;
	}
	anim = new SDL_Rect[nbFrames];

	// fill it
	for (int i = 0; i < nbFrames; i++) {
		if (horz) {
			// offset the images on the x axis
			anim[i].x = xSrc + i * wSrc + i * offsetSrc;
			anim[i].y = ySrc;
		} else {
			// offset the images on the y axis
			anim[i].x = xSrc;
			anim[i].y = ySrc + i * hSrc + i * offsetSrc;
		}

		// the width and height will always be the same, no matter if its vertical or horizontal
		anim[i].w = wSrc;
		anim[i].h = hSrc;
	}

	// start out at the first frame
	SetSrcRect(anim[0]);
}

void Animation::Update(float dt) {
	// perform those operations only while it is visible
	if (isVisible) {
		// increment the current time
		currentTime += dt;

		// do nothing if 0 frames, would divide by 0
		if (nbFrames != 0 && frameRate != 0.0f) {
			// get the current frame and keep it from 0 to max frame
			currentFrame = (int)(currentTime / frameRate);
			currentFrame %= nbFrames;

			// if it doesnt loop, make it stop looping and fix on the first image
			if (!isLooping && currentTime >= nbFrames * frameRate) {
				// it doesn't loop and did a full cycle, so display the first frame only
				SetSrcRect(anim[0]);
			} else {
				// it loops keep displaying the current frame
				SetSrcRect(anim[currentFrame]);
			}
		}
	}
}

Animation::~Animation()
{
	delete[] anim;
}